#include "asynframeimpl.h"
#include "fileimpl.h"
#include "tcpsocketimpl.h"
#include "udpsocketimpl.h"
#include "tcplistensocketimpl.h"
#include "timerimpl.h"
#include "iooperationimpl.h"

CAsynFrameImpl::CAsynFrameImpl(void)
{

}

CAsynFrameImpl::~CAsynFrameImpl(void)
{
	logi("CAsynFrameImpl::~CAsynFrameImpl");
}

std_method_impl CAsynFrameImpl::Init(int Argc, basic_tchar* Argv[], IBase* pRot, IBase* pBase)
{
	rc_assert(pRot != NULL, E_FAIL)

	HRESULT hr = S_OK;
	hr = pRot->QueryInterface(IID_IComRunningObjectTable, (void**)&m_pRot);
	rc_assert(hr == S_OK, E_FAIL)

	return S_OK;
}
std_method_impl CAsynFrameImpl::Uninit()
{
	return S_OK;
}
std_method_impl CAsynFrameImpl::Start(_pinstance hInstance, UINT uType)
{
	InitSocketEnv(2, 0);
	m_pContextPool = ALLOC_NEW io_contextpool_t;

	set_instance(m_pContextPool);
	contexts_init(2);
	CThread::Start_Thread();
	this->m_asynframe_sem.Wait();
	return S_OK;
}
std_method_impl CAsynFrameImpl::Stop(UINT uExitCode)
{
	CThread::Stop_Thread();
	contexts_uninit();
	UnInitSocketEnv(2, 0);
	
	return S_OK;
}
std_method_impl CAsynFrameImpl::CreateIo(IO_Protocol iop, IBase** pBase)
{
	if (io_operation == iop)
	{
		return CreateAsynIoOperation(pBase);
	}
	else if (io_tcp_socket == iop)
	{
		return CreateTcpSocket(pBase);
	} 
	else if (io_tcplisten_socket == iop)
	{
		return CreateTcpListenSocket(pBase);
	}
	else if (io_udp_socket == iop)
	{
		return CreateUdpSocket(pBase);
	}
	else if (io_udplisten_socket == iop)
	{
		return E_FAIL;
	}
	else if (io_timer == iop)
	{
		return CreateTimer(pBase);
	}
	else if (io_file == iop)
	{
		return CreateFile(pBase);
	}

	return E_FAIL;
}

void async_post(void* data)
{

}
std_method_impl CAsynFrameImpl::PostIo(IBase* pOperation)
{
	int rc = S_SUCCESS;
	rc = contexts_post(async_post, pOperation);
	return rc == S_SUCCESS? S_OK : E_FAIL;
}
std_method_impl CAsynFrameImpl::Thread_Init()
{
	return S_OK;
}
std_method_impl CAsynFrameImpl::Thread_Run()
{
	SetService(true);
	contexts_start(this);
	return S_OK;
}
std_method_impl CAsynFrameImpl::Thread_UnInit()
{
	contexts_stop();
	return S_OK;
}
std_method_impl CAsynFrameImpl::SetService(bool bstart)
{
	if (bstart)
	{
		this->m_asynframe_sem.Post();
	}
	return S_OK;
}
std_method_impl CAsynFrameImpl::CreateAsynIoOperation(IBase **ppOperation)
{
	CIoOperationImpl* pObject = NULL;
	pObject = ALLOC_NEW CIoOperationImpl;
	rc_assert(pObject != NULL, E_FAIL)
	return pObject->QueryInterface(IID_IOperation, (void**)ppOperation);
}
std_method_impl CAsynFrameImpl::CreateFile(IBase** pFile)
{
	CFileImpl*	pObject = NULL;
	pObject = ALLOC_NEW CFileImpl;
	rc_assert(pObject != NULL, E_FAIL)
	return pObject->QueryInterface(IID_IFile, (void**)pFile);;
}
std_method_impl CAsynFrameImpl::CreateTcpSocket(IBase** pAsynTcpSocket)
{
	CTcpSocketImpl*	pObject = NULL;
	pObject = ALLOC_NEW CTcpSocketImpl;
	pObject->tcp_create(get_instance());
	return pObject->QueryInterface(IID_ITcpSocket, (void**)pAsynTcpSocket);
}
std_method_impl CAsynFrameImpl::CreateUdpSocket(IBase** pAsynUdpSocket)
{
	CUdpSocketImpl*	pObject = NULL;
	pObject = ALLOC_NEW CUdpSocketImpl;
	rc_assert(pObject != NULL, E_FAIL)
	pObject->udp_create(get_instance());
	return pObject->QueryInterface(IID_IUdpSocket, (void**)pAsynUdpSocket);
}
std_method_impl CAsynFrameImpl::CreateTcpListenSocket(IBase** pAsynTcpListenSocket)
{
	HRESULT		hr = S_OK;
	CTcpListenSocketImpl *pObject = NULL;
	pObject = ALLOC_NEW CTcpListenSocketImpl;
	rc_assert(pObject != NULL, E_FAIL)
	pObject->accpet_create(get_instance());
	return pObject->QueryInterface(IID_ITcpListen, (void**)pAsynTcpListenSocket);
}
std_method_impl CAsynFrameImpl::CreateTimer(IBase** pTimer)
{
	CTimerImpl *pObject = NULL;
	pObject = ALLOC_NEW CTimerImpl();
	rc_assert(pObject != NULL, E_FAIL)
	pObject->time_create(get_instance());
	return pObject->QueryInterface(IID_ITimer, (void**)pTimer);
}


